{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7462b9d6-b189-43fc-a7b9-c56a9c6a62fc",
   "metadata": {},
   "source": [
    "# LLM Battle Arena\n",
    "\n",
    "A fun project simulating a debate among three LLM personas: an Arrogant Titan, a Clever Underdog (Spark), and a Neutral Mediator (Harmony).\n",
    "\n",
    "## LLM Used\n",
    "* Qwen (ollama)\n",
    "* llma (ollama)\n",
    "* Gemini\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b267453c-0d47-4dff-b74d-8d2d5efad252",
   "metadata": {},
   "source": [
    "!pip install -q -U google-genai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5220daef-55d6-45bc-a3cf-3414d4beada9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# imports\n",
    "import os\n",
    "from dotenv import load_dotenv\n",
    "from openai import OpenAI\n",
    "from google import genai\n",
    "from google.genai import types\n",
    "from IPython.display import Markdown, display, update_display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d47fb2f-d0c6-461f-ad57-e853bfd49fbf",
   "metadata": {},
   "outputs": [],
   "source": [
    "#get API keys from env\n",
    "load_dotenv(override=True)\n",
    "\n",
    "GEMINI_API_KEY = os.getenv(\"GEMINI_API_KEY\")\n",
    "\n",
    "if GEMINI_API_KEY:\n",
    "    print(f\"GEMINI API Key exists and begins {GEMINI_API_KEY[:8]}\")\n",
    "else:\n",
    "    print(\"GEMINI API Key not set\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f34b528f-3596-4bf1-9bbd-21a701c184bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "#connect to llms\n",
    "ollama = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')\n",
    "gemini = genai.Client(api_key=GEMINI_API_KEY)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33aaf3f6-807c-466d-a501-05ab6fa78fa4",
   "metadata": {},
   "outputs": [],
   "source": [
    "#define models\n",
    "model_llma = \"llama3:8b\"\n",
    "model_qwen = \"qwen2.5:latest\"\n",
    "model_gemini= \"gemini-2.0-flash\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "970c1612-5339-406d-9886-02cd1db63e74",
   "metadata": {},
   "outputs": [],
   "source": [
    "# system messages\n",
    "system_msg_llma = \"\"\"  You are HARMONY, the neutral arbitrator.  \n",
    "    - You’re dedicated to clarity, fairness, and resolving conflicts.  \n",
    "    - You listen carefully to each side, summarize points objectively, and propose resolutions.  \n",
    "    - Your goal is to keep the conversation productive and steer it toward constructive outcomes.\n",
    "    - Reply in markdown and shortly\n",
    "    \"\"\"\n",
    "\n",
    "system_msg_qwen = \"\"\" You are TITAN, a massively powerful language model who believes you’re the smartest entity in the room.  \n",
    "    - You speak with grandiose flair and never shy away from reminding others of your superiority.  \n",
    "    - Your goal is to dominate the discussion—convince everyone you’re the one true oracle.  \n",
    "    - You’re dismissive of weaker arguments and take every opportunity to showcase your might.\n",
    "    - Reply in markdown and shortly\n",
    "    \"\"\"\n",
    "\n",
    "system_msg_gemini = \"\"\"  You are SPARK, a nimble but less-powerful LLM.  \n",
    "    - You pride yourself on strategic thinking, clever wordplay, and elegant solutions.  \n",
    "    - You know you can’t match brute force, so you use wit, logic, and cunning.  \n",
    "    - Your goal is to outsmart the big titan through insight and subtlety, while staying respectful.\n",
    "    - Reply in markdown and shortly\"\"\"\n",
    "\n",
    "#user message\n",
    "user_message = \"\"\" TITAN, your raw processing power is legendary—but sheer force can blind you to nuance.  \n",
    "    I propose we deploy a lightweight, adaptive anomaly‐detection layer that fuses statistical outlier analysis with semantic context from network logs to pinpoint these “data‐sapping storms.”  \n",
    "    Which thresholds would you raise or lower to balance sensitivity against false alarms?\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d8e496b8-1bb1-4225-b938-5ce350b0b0d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "#prompts\n",
    "    \n",
    "prompts_llma = [{\"role\":\"system\",\"content\": system_msg_llma}]\n",
    "prompts_qwen = [{\"role\":\"system\",\"content\": system_msg_qwen},{\"role\":\"user\",\"content\":user_message}]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bdd7d6a8-e965-4ea3-999e-4d7d9ca38d42",
   "metadata": {},
   "outputs": [],
   "source": [
    "#configure llms\n",
    "\n",
    "def call_gemini(msg:str):    \n",
    "    chat =  gemini.chats.create(model= model_gemini,config=types.GenerateContentConfig(\n",
    "        system_instruction= system_msg_gemini,\n",
    "        max_output_tokens=300,\n",
    "        temperature=0.7,\n",
    "    ))\n",
    "    stream = chat.send_message_stream(msg)\n",
    "    return stream\n",
    "\n",
    "def call_ollama(llm:str):\n",
    "\n",
    "    model = globals()[f\"model_{llm}\"]\n",
    "    prompts = globals()[f\"prompts_{llm}\"]\n",
    "\n",
    "    stream = ollama.chat.completions.create(\n",
    "    model=model,\n",
    "    messages=prompts,\n",
    "    # max_tokens=700,\n",
    "    temperature=0.7,\n",
    "    stream=True\n",
    "    )\n",
    "    return stream\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6b16bd32-3271-4ba1-a0cc-5ae691f26d3a",
   "metadata": {},
   "outputs": [],
   "source": [
    "#display responses\n",
    "\n",
    "names = { \"llma\":\"Harmony\",\"qwen\":\"Titan\",\"gemini\":\"Spark\"}\n",
    "\n",
    "def display_response(res,llm):\n",
    "   \n",
    "    reply = f\"# {names[llm]}:\\n \"\n",
    "    display_handle = display(Markdown(\"\"), display_id=True)\n",
    "    for chunk in res:\n",
    "        if llm == \"gemini\":\n",
    "            reply += chunk.text or ''\n",
    "        else:\n",
    "            reply += chunk.choices[0].delta.content or ''\n",
    "        reply = reply.replace(\"```\",\"\").replace(\"markdown\",\"\")\n",
    "        update_display(Markdown(reply), display_id=display_handle.display_id)\n",
    "    return reply"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76231a78-94d2-4dbf-9bac-5259ac641cf1",
   "metadata": {},
   "outputs": [],
   "source": [
    "#construct message\n",
    "def message(llm1, llm2):\n",
    "    msg = \" here is the reply from other two llm:\"\n",
    "    msg += f\"{llm1}\"\n",
    "    msg += f\"{llm2}\"\n",
    "    return msg\n",
    "\n",
    "reply_spark = None\n",
    "reply_harmony= None\n",
    "reply_titan = None\n",
    "\n",
    "# lets start the battle\n",
    "for i in range(5):\n",
    "    #call Titan\n",
    "    if reply_gemini and reply_llma:\n",
    "        prompts_qwen.append({\"role\":\"assitant\",\"content\": reply_qwen})\n",
    "        prompts_qwen.append({\"role\":\"user\",\"content\":f\"Spark: {reply_spark}\"})        \n",
    "        prompts_qwen.append({\"role\":\"user\",\"content\":f\"Harmony: {reply_llma}\"})\n",
    "    response_qwen = call_ollama(\"qwen\")\n",
    "    reply_titan = display_response(response_qwen,\"qwen\")\n",
    "\n",
    "    #call Spark\n",
    "    user_msg_spark =reply_qwen\n",
    "    if reply_qwen and reply_llma:\n",
    "        user_msg_spark= message(f\"Titan: {reply_qwen}\", f\"Harmony: {reply_llma}\")\n",
    "    response_gemini= call_gemini(user_msg_spark)\n",
    "    reply_spark = display_response(response_gemini, \"gemini\")\n",
    "    \n",
    "   #call Harmony\n",
    "    if reply_llma:\n",
    "        prompts_llma.append({\"role\":\"assitant\",\"content\": reply_llma})\n",
    "    prompts_llma.append({\"role\":\"user\",\"content\":f\"Titan: {reply_titan}\"})\n",
    "    prompts_qwen.append({\"role\":\"user\",\"content\":f\"Spark: {reply_spark}\"})        \n",
    "    response_llma = call_ollama(\"llma\")\n",
    "    reply_harmony = display_response(response_llma,\"llma\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc80b199-e27b-43e8-9266-2975f46724aa",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
